﻿using System;
using System.Linq;
using System.Web.Security;
using ELearningSystem.Core.Interface;
using ELearningSystem.DAO.DAO;
using ELearningSystem.Gateway.Entities;
using ELearningSystem.Gateway.Gateway;
using ELearningSystem.Core.Manager.ExtensionMethod;

namespace ELearningSystem.Core.Manager
{
    public class UserManager : IUserManager
    {
        private UserGateway userGateway = new UserGateway();
        private PracticeGateway practiceGateway = new PracticeGateway();

        public LearnerDAO GetLearnerWithEmail(string emailAddress)
        {
            return userGateway.GetLearnerUsingEmail(emailAddress).ToLearnerDAO();
        }
        public bool IsAuthenticatedUser(LearnerDAO aLearner, out LearnerDAO authenticatedLearner)
        {
            LearnerDAO searchedLearner = userGateway.GetLearnerUsingEmail(aLearner.ToLearnerEntity().EmailAddress).ToLearnerDAO();

            bool isAuthenticated = IsAuthenticated(searchedLearner, aLearner,"Learner");

            authenticatedLearner = isAuthenticated ? searchedLearner : null;

            return isAuthenticated;
        }

        private bool IsAuthenticated(LearnerDAO searchedLearner,LearnerDAO aLearner, string role)
        {
            if (searchedLearner!=null)
            {
                if (searchedLearner.Password==aLearner.Password && searchedLearner.Role==role)
                {
                    return true;
                }
            }
            return false;
        }

        public bool IsAdmin(LearnerDAO aLearner)
        {
            LearnerDAO searchedLearner = userGateway.GetLearnerUsingEmail(aLearner.ToLearnerEntity().EmailAddress).ToLearnerDAO();

            return IsAuthenticated(searchedLearner, aLearner, "Admin");
        }

        public LearnerDAO GetLearnerWithName(string name)
        {
            return userGateway.GetLearnerWithName(name).ToLearnerDAO();
        }

        public ScoreViewDAO GetUpdatedScore(LearnerDAO aLearner)
        {
            ScoreViewDAO score = new ScoreViewDAO();
            score.TotalPractices = practiceGateway.GetAll().Count(practice => practice.Question!=null);
            score.AttemptedOnTotal = score.TotalPractices==0?0:(double)(aLearner.Attempts.Count*100)/score.TotalPractices;
            score.PassedOnTotal = score.TotalPractices == 0 ? 0 : (double)GetPassedAmount(aLearner)*100/score.TotalPractices;
            score.PassedOnAttempted = aLearner.Attempts.Count==0?0:(double)GetPassedAmount(aLearner)*100/aLearner.Attempts.Count;
            return score;
        }

        private int GetPassedAmount(LearnerDAO aLearner)
        {
            var passedAttempts = aLearner.Attempts.Where(attempt => attempt.IsCorrect == true);
            return passedAttempts.Count();
        }

        public ScoreViewDAO UpdateScoreAndReturnLatestScore(LearnerDAO learner, AttemptDAO attempt)
        {
            bool found = false;
            foreach (var anAttempt in learner.Attempts)
                if (anAttempt.Practice.Id.Equals(attempt.Practice.Id))
                {
                    anAttempt.IsCorrect = attempt.IsCorrect;
                    found = true;
                    break;
                }
            if (!found)
                learner.Attempts.Add(attempt);
            userGateway.SaveOrUpdate(learner.ToLearnerEntity());
            learner = GetLearnerWithName(learner.Name);
            return GetUpdatedScore(learner);
        }

        public bool SaveOrUpdateLearner(LearnerDAO learner, out string message)
        {
            message = "";
            if (userGateway.GetLearnerWithName(learner.Name)!=null)
            {
                message = "UserName already Exists!";
                return false;
            }
            else if (userGateway.GetLearnerUsingEmail(learner.EmailAddress)!=null)
            {
                message = "Email Address Already exists!";
                return false;
            }
            else
            {
                
                if (userGateway.SaveOrUpdate(learner.ToLearnerEntity()))
                {
                    message = "Signed-Up Successfully! Please Login your Credentials";
                    return true;
                }
                else
                {
                    throw new Exception("Sign-up failed");
                }
            }
        }

        
    }
}
